package com.wjh.anyview.websocket.server;

import com.wjh.anyview.util.SpringUtil;
import com.wjh.anyview.websocket.entity.bo.TopicMessage;
import com.wjh.anyview.websocket.util.SecurityUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author wjh
 * @date 2021/10/23 16:12
 * @Package com.wjh.anyview.websocket.server
 */
@Component
@ServerEndpoint("/server/TeacherLoginServer/{userId}")
@Slf4j
public class TeacherLoginServer {
    /**
     * 用户存储所有在线（即未断开websocket连接）用户
     */
    public final static Map<String, Session> ONLINE_TEACHERS_MAP = new ConcurrentHashMap<>();

    /**
     * session.toString-->num
     */
    public final static Map<String, String> TEACHER_NUM_MAP = new ConcurrentHashMap<>();

    /**
     * 引入redis
     */
    private final StringRedisTemplate redisTemplate = SpringUtil.getBean("getRedisTemplate");

    /**
     * 连接建立成功调用的方法
     */
    @OnOpen
    public void onOpen(Session session, @PathParam("userId") String num) {
        log.info(num + "成功与服务器建立websocket连接");
        //如果用户不在线，则让他处于在线状态
        if (!ONLINE_TEACHERS_MAP.containsKey(num)) {
            ONLINE_TEACHERS_MAP.put(num, session);
            TEACHER_NUM_MAP.put(session.toString(), num);
        }
    }

    public void sendTopicMessageToChrome(String topicMessage) {
        TopicMessage decodeTopicMessage = SecurityUtil.decodeTopicMessage(topicMessage);
        //获取需要发送的教师的numList
        String numListTeacher = redisTemplate.opsForValue().get(decodeTopicMessage.getKey());
        assert numListTeacher != null;
        List<String> list = Arrays.asList(numListTeacher.split(","));
        log.info("需要发送教师的集合：" + list);
        //存放session存活的list
        List<Session> sessionNotNullList = new ArrayList<>();
        list.forEach(num -> {
            //获取该工号对应的session
            Session session = ONLINE_TEACHERS_MAP.get(num);
            //需要通知的老师在线
            if (session != null) {
                sessionNotNullList.add(session);
            } else {
                log.warn("wsSession为null");
            }
        });

        log.info("可以发送消息的session：" + sessionNotNullList);
        //利用session发送消息
        sessionNotNullList.forEach(session -> {
            try {
                //给对应用户发送消息
                session.getBasicRemote().sendText(decodeTopicMessage.getMessage());
            } catch (IOException e) {
                e.printStackTrace();
            }
        });
    }

    public static void sendToChrome(String message, String num) throws IOException {
        Session session = ONLINE_TEACHERS_MAP.get(num);
        //给对应用户发送消息
        session.getBasicRemote().sendText(message);
    }

    @OnClose
    public void onClose(Session session) {
        String num = TEACHER_NUM_MAP.get(session.toString());
        ONLINE_TEACHERS_MAP.remove(num);
        log.warn("连接中断...");
    }

    /**
     * 收到客户端消息后调用的方法
     */
    @OnMessage
    public void onMessage(String message, Session session) {

    }

    public void getRedisMessage(String topicMessage) {
        log.info("收到的mq消息：" + topicMessage);
        sendTopicMessageToChrome(topicMessage);
    }
}
